#include "StdAfx.hpp"
#include "MeshAccumulator.hpp"
#include "Mesh.hpp"
#include "VertexDecl.hpp"


MeshAccumulator::MeshAccumulator()
{

}

MeshAccumulator::~MeshAccumulator()
{

}

void MeshAccumulator::Clear()
{
	m_Indices.clear();
	m_Vertices.clear();
}

void MeshAccumulator::ConvertToMesh( Mesh &dst )
{
	dst.Clear();

	VertexDecl decl;
	decl.AddByUsage(0, D3DDECLUSAGE_POSITION, D3DDECLTYPE_FLOAT3, 0);
	decl.AddByUsage(0, D3DDECLUSAGE_NORMAL,   D3DDECLTYPE_FLOAT3, 0);
	decl.AddByUsage(0, D3DDECLUSAGE_TEXCOORD, D3DDECLTYPE_FLOAT2, 0);

	dst.CreateVB(m_Vertices.size(), decl);
	{
		Mesh::VBLock vbLock(dst);
		memcpy(vbLock.GetPtr(), &m_Vertices[0], m_Vertices.size()*sizeof(VERTEX_XN2));
	}

	D3DFORMAT indexFormat = m_Vertices.size() < 0xFFFF ? D3DFMT_INDEX16 : D3DFMT_INDEX32;
	dst.CreateIB(m_Indices.size(), indexFormat);
	{
		Mesh::IBLock ibLock(dst);
		if (indexFormat == D3DFMT_INDEX32)
			memcpy(ibLock.GetPtr(), &m_Indices[0], m_Indices.size()*sizeof(uint));
		else
		{
			uint2 *ib = (uint2*)ibLock.GetPtr();
			for (uint i = 0; i < m_Indices.size(); i++)
				*(ib++) = (uint2)m_Indices[i];
		}
	}
}

void MeshAccumulator::AddQuad( const common::VEC3 &point1, const common::VEC3 &vec1, const common::VEC3 &vec2, const common::RECTF &texCoords )
{
	VEC3 normal;
	Cross(&normal, vec2, vec1);
	Normalize(&normal);

	uint baseIndex = m_Vertices.size();

	VERTEX_XN2 v;
	v.Pos = point1;
	v.Normal = normal;
	v.Tex = VEC2(texCoords.Min.x, texCoords.Min.y);
	m_Vertices.push_back(v);
	v.Pos = point1 + vec1;
	v.Normal = normal;
	v.Tex = VEC2(texCoords.Max.x, texCoords.Min.y);
	m_Vertices.push_back(v);
	v.Pos = point1 + vec2;
	v.Normal = normal;
	v.Tex = VEC2(texCoords.Min.x, texCoords.Max.y);
	m_Vertices.push_back(v);
	v.Pos = point1 + vec1 + vec2;
	v.Normal = normal;
	v.Tex = VEC2(texCoords.Max.x, texCoords.Max.y);
	m_Vertices.push_back(v);

	m_Indices.push_back(baseIndex  );
	m_Indices.push_back(baseIndex+2);
	m_Indices.push_back(baseIndex+3);

	m_Indices.push_back(baseIndex  );
	m_Indices.push_back(baseIndex+3);
	m_Indices.push_back(baseIndex+1);
}
